package com.xoms.admin.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.xoms.admin.controller.res.bean.RProAllotBean;
import com.xoms.admin.controller.res.bean.RProAllotDetailBean;
import com.xoms.admin.model.AccountBean;
import com.xoms.admin.model.ProAllotBean;
import com.xoms.admin.model.ProAllotDetailBean;
import com.xoms.admin.model.ProStockBean;
import com.xoms.admin.model.vo.BatchAllotBean;
import com.xoms.admin.model.vo.ProAllotVo;
import com.xoms.admin.persist.dao.ProAllotDao;
import com.xoms.admin.persist.dao.ProStockDao;
import com.xoms.admin.service.ProAllotService;
import com.xoms.admin.service.exception.ServiceException;
import com.xoms.admin.service.res.PageResult;
import com.xoms.util.AppTextUtil;
import com.xoms.util.DateTimeUtil;
import com.xoms.util.NumUtil;
import com.xoms.util.StringUtil;

@Service
public class ProAllotServiceImpl implements ProAllotService {

	Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	ProAllotDao proAllotImpl;

	@Autowired
	ProStockDao proStockImpl;

	@Override
	public PageResult<RProAllotBean> getAllots(AccountBean account, String key, int page, int pageSize, String startTime,
			String endTime, String fromId, String toId) {

		PageResult<RProAllotBean> result = new PageResult<RProAllotBean>();
		List<RProAllotBean> resList = new ArrayList<RProAllotBean>();

		// 查询调拨数量
		int count = proAllotImpl.selectCount(key, fromId, toId, startTime, endTime);
		// 查询调拨列表
		if (count > 0) {
			List<ProAllotBean> lists = proAllotImpl.selectList(key, page, pageSize, fromId, toId, startTime, endTime);
			if (lists != null) {
				RProAllotBean pa = null;
				for (ProAllotBean a : lists) {
					pa = new RProAllotBean();
					pa = parse(a);
					resList.add(pa);
				}
			}
		}
		result.setData(resList);
		result.setCount(count);
		return result;
	}

	/**
	 * 格式化数据
	 * 
	 * @param punit
	 * @return
	 */
	private RProAllotBean parse(ProAllotBean allot) {
		RProAllotBean res = new RProAllotBean();
		res.setAid(allot.getAid());
		res.setAccount(allot.getAccount());
		res.setAllotNo(allot.getAllotNo());
		res.setFromStore(allot.getFromStore());
		res.setToStore(allot.getToStore());
		res.setType(allot.getType());
		res.setRemark(allot.getRemark());
		res.setFromId(allot.getFromId());
		res.setToId(allot.getToId());
		res.setTargetId(allot.getTargetId());
		res.setCreateTime(DateTimeUtil.formatTimestamp(allot.getCreateTime()));
		return res;
	}

	@Override
	public PageResult<RProAllotDetailBean> getAllotDetail(AccountBean account, String key, int page, int pageSize,
			String allotId, int paging) {
		PageResult<RProAllotDetailBean> result = new PageResult<RProAllotDetailBean>();
		List<RProAllotDetailBean> resList = new ArrayList<RProAllotDetailBean>();
		// 查询调拨数量
		int count = proAllotImpl.selectDetailCount(key, allotId);
		// 查询调拨列表
		if (count > 0) {
			List<ProAllotDetailBean> lists = proAllotImpl.selectDetailList(key, page, pageSize, allotId);
			if (lists != null) {
				RProAllotDetailBean pad = null;
				for (ProAllotDetailBean acc : lists) {
					pad = new RProAllotDetailBean();
					pad = parseDateil(acc);
					resList.add(pad);
				}
			}
		}
		result.setData(resList);
		result.setCount(count);
		return result;
	}

	/**
	 * 格式化数据
	 * 
	 * @param punit
	 * @return
	 */
	private RProAllotDetailBean parseDateil(ProAllotDetailBean allot) {
		RProAllotDetailBean res = new RProAllotDetailBean();
		res.setAllotId(allot.getAllotId());
		res.setPrice(allot.getPrice());
		res.setCreateTime(DateTimeUtil.formatTimestamp(allot.getCreateTime()));
		res.setCategory(allot.getCategory());
		res.setProduct(allot.getProduct());
		res.setProductId(allot.getProductId());
		res.setProductBar(allot.getProductBar());
		res.setUnit(allot.getUnit());
		res.setNumber(allot.getNumber());
		return res;
	}

	@Transactional(rollbackFor = Exception.class) // 事务
	@Override
	public RProAllotBean edit(AccountBean account, String aid, String fromId, String toId, String remark,
			int type, String details, String targetId) {
		boolean flag = false;
		ProAllotBean data = new ProAllotBean();
		data.setFromId(fromId);
		data.setToId(toId);
		data.setRemark(remark);
		data.setType(type);
		data.setTargetId(targetId);

		if(fromId.equals(toId)) {
			throw new ServiceException("allot_store_can_not_same");
		}
		if (StringUtil.isEmpty(aid)) { // 新建
			aid = AppTextUtil.getPrimaryKey();// id
			
			// 调拨编号：DB + YYYYMMDDHHmm + 0000001;一年百万数据？
			String maxNo = proAllotImpl.selectMaxAllotNoInYear(type);// 获取当年采购单最大数量
			int num = 0;
			if(!StringUtil.isEmpty(maxNo)) {
				num = NumUtil.toInt(maxNo.substring(maxNo.length() - 7, maxNo.length()), 0);
			}
			String allotNo = AppTextUtil.getRandomProNo("DB", (num + 1), 7);
			data.setAllotNo(allotNo);
			data.setAid(aid);
			data.setAccountId(account.getAccid());
			flag = proAllotImpl.insert(data) > 0;
			if (!flag) {
				throw new ServiceException("database_insert_fail", "调拨");
			}
		} else {// 修改
			data.setAid(aid);
			flag = proAllotImpl.update(data) > 0;// 更新数据库
			if (!flag) {
				throw new ServiceException("database_update_fail", "调拨");
			}
		}
		// 将调拨详情信息批量插入数据库 
		// 判断数量
		int detailCount = proAllotImpl.selectDetailCountById(aid);
		if(detailCount > 0) {
			// 删除当前采购单下所有关联采购单详情
			flag = proAllotImpl.delDetailByAId(aid) > 0;
			if (!flag) {
				throw new ServiceException("database_delete_fail", "调拨单详情");
			}
		}
		if (!StringUtil.isEmpty(details)) {
			flag = replaceBatchDetail(aid, fromId, toId, details);
		}
		ProAllotBean info = proAllotImpl.selectOneById(aid);
		return parse(info);
	}
	
	/**
	 * 将调拨详情信息批量插入数据库
	 * @param aid
	 * @param fromId
	 * @param toId
	 * @param details
	 * @return
	 */
	private boolean replaceBatchDetail(String aid, String fromId, String toId, String details) {
		boolean flag = false;
		// json 转List
		List<BatchAllotBean> batch = JSON.parseArray(details, BatchAllotBean.class);
		for (BatchAllotBean pure : batch) {
			pure.setAllotId(aid);
		}
		if (batch.size() > 0) {
			flag = proAllotImpl.replaceBatchDetail(batch) > 0;
			if (!flag) {
				throw new ServiceException("database_insert_fail", "调拨单详情");
			}
			
			// 更新来源库和目标库存储商品数量
			List<ProStockBean> newStocks = new ArrayList<>();
			
			// 调拨商品的来源库的库存数量和调拨数量
			List<ProAllotVo> formStores = proAllotImpl.selectNumberByAidInType(aid, 1);// type 1 来源库，2 目标库
			List<ProAllotVo> toStores = proAllotImpl.selectNumberByAidInType(aid, 2);// type 1 来源库，2 目标库
			if (formStores != null) {
				ProStockBean fps = null;
				ProStockBean tps = null;
				for (ProAllotVo allot : formStores) {
					if(allot.getNumber() > allot.getStore()){ 
						throw new ServiceException("allot_number_over_error");
					}
					fps = new ProStockBean();
					tps = new ProStockBean();
					fps.setProductId(allot.getProductId());
					fps.setCost(allot.getCost());
					fps.setAccountId(allot.getAccountId());
					fps.setRemark(allot.getRemark());
					fps.setStoreHouseId(allot.getStoreId());
					fps.setStore(allot.getStore() - allot.getNumber());// 来源库存数量减去调拨数量
					newStocks.add(fps);
					ProAllotVo tp = new ProAllotVo(allot.getStoreId(), allot.getProductId());
					tps = new ProStockBean();
					tps.setProductId(allot.getProductId());
					tps.setStoreHouseId(toId);
					if(toStores != null && toStores.contains(tp)) {
						int index = toStores.indexOf(tp);
						ProAllotVo toStore = toStores.get(index);
						tps.setCost(toStore.getCost());
						tps.setAccountId(toStore.getAccountId());
						tps.setRemark(toStore.getRemark());
						tps.setStore(toStore.getStore() + allot.getNumber());// 目标库存数量加上调拨数量
						newStocks.add(tps);
					} else {
						tps.setCost(allot.getCost());
						tps.setAccountId(allot.getAccountId());
						tps.setRemark("出库入柜");
						tps.setStore(allot.getNumber());// 调拨数量
						newStocks.add(tps);
					}
					
				}
				logger.info("newStocks-----" + JSON.toJSONString(newStocks));
				// 批量更新
				flag = proStockImpl.replaceStocks(newStocks) > 0;
				if (!flag) {// 更新状态失败
					throw new ServiceException("database_update_fail", "库存");
				}
			}
			
		}
		
		return flag;
	}

	@Transactional(rollbackFor = Exception.class) // 事务
	@Override
	public boolean del(AccountBean account, String aid) {
		boolean flag = false;
		ProAllotBean allot = proAllotImpl.selectOneById(aid);
		if(allot == null) {// 采购单不存在
			throw new ServiceException("object_is_not_exist","调拨单");
		}
		flag = proAllotImpl.del(aid) > 0;
		if (!flag) {
			throw new ServiceException("database_delete_fail", "调拨单");
		}
		// 删除详情
		// 判断数量
		int detailCount = proAllotImpl.selectDetailCountById(aid);
		if(detailCount > 0) {
			// 删除当前采购单下所有关联采购单详情
			flag = proAllotImpl.delDetailByAId(aid) > 0;
			if (!flag) {
				throw new ServiceException("database_delete_fail", "调拨单详情");
			}
		}
		return flag;
	}

}
